<template>
    <div style="position: relative;">
        <!-- <div style="width: 1000px;height: 40px;background-color: rgba(255,255,0,.5);position: absolute;"></div> -->
        <div style="width: 1000px;height: 600px;" ref="chart"></div>
    </div>
</template>

<script setup>
import * as echarts from 'echarts';
import { ref, onMounted } from 'vue';
let chart = ref();
onMounted(() => {
    let chartDom = chart.value;
    let myChart = echarts.init(chartDom);
    let data = [
        { value: 20, name: 'Visit' },
        { value: 30, name: 'Visit1' },
        { value: 40, name: 'Visit2' },
        { value: 60, name: 'Visit3' },
        { value: 50, name: 'Visit4' },
    ]
    // 设置颜色-因为用到事件动态setoption了自带颜色不保熟
    let colors = ['#5c7bd9', '#91cc75', '#fac858', '#ee6666', '#73c0de']
    data.map((v, k) => {
        v['itemStyle'] = { color: colors[k] }
    })
    let legendData = data.map((v) => v.name);

    // 是否平均分配宽度
    let isAverageWidth_ = false;

    // 最大 100（表示为百分比） 可以在37行吧 '%' 去掉设置数值
    let maxBarHeight = 30;

    /**
     * 函数描述
     * @param {array} fnData 数据
     * @param {boolean} isAverageWidth 是否固定宽度（固定的宽度根据100/fnData长度）
     * @param {number=} maxBarHeight 柱子的最大高度
     * @return {array} 处理后的series
     */
    const computedData = (fnData, isAverageWidth, maxBarHeight) => {
        let newData = [];
        let count = fnData.map((v) => v.value).reduce((a, b) => {
            return a + b;
        }, 0);

        let averageWidth = 100 / fnData.length;
        fnData.forEach((item, index) => {
            let proportion = item.value / count;
            let size = maxBarHeight * proportion + '%';
            let barWidth = averageWidth + '%';
            let leftOffset = 0;
            if (isAverageWidth) {
                barWidth = averageWidth + '%';
                leftOffset = averageWidth * index + '%';
            } else {
                let barWidthNum = 100 * proportion
                barWidth = barWidthNum + '%'
                for (let i = 0; i < index; i++) {
                    let proportion_ = fnData[i].value / count;
                    leftOffset += 100 * proportion_
                }
                leftOffset += '%';
            }

            let seriesItem = {
                name: item.name,
                type: 'funnel',
                orient: 'horizontal',
                width: barWidth,
                left: leftOffset,
                minSize: size,
                maxSize: size,
                top: "-20%", //上下位置
                sort: 'descending',
                gap: 2,
                label: {
                    show: true,
                    position: 'inside'
                },
                labelLine: {
                    length: 10,
                    lineStyle: {
                        width: 1,
                        type: 'solid'
                    }
                },
                itemStyle: {
                    borderColor: '#fff',
                    borderWidth: 0,
                    opacity: item.value == 0 ? 0 : 1
                },
                emphasis: {
                    label: {
                        fontSize: 14
                    }
                },
                data: [
                    item
                ]
            }

            newData.push(seriesItem)
        })
        return newData;
    }
    let resData = computedData(data, isAverageWidth_, maxBarHeight);

    let option = {
        tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c}'
        },
        legend: {
            data: legendData,
            top: "10%"
        },
        grid: {
            containLabel: true,
            left: 0,
            bottom: 0,
            right: 0,
            top: 0
        },
        color: colors,
        series: resData
    };

    myChart.on('legendselectchanged', function (lparam) {
        let selects = lparam.selected;
        let newDataFilter = [];
        data.filter((item) => {
            if (selects[item.name]) {
                newDataFilter.push(item);
            } else {
                let clone = {
                    ...item,
                    value: 0
                }
                newDataFilter.push(clone)
            }
        })
        let resData = computedData(newDataFilter, isAverageWidth_, maxBarHeight);
        myChart.setOption({
            series: resData
        })
    })
    myChart.setOption(option)
})
</script>